home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i084: Logfile monitor tool for Suns
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Steven Grimm <koreth@ssyx.ucsc.edu>
- Posting-number: Volume 16, Issue 84
- Archive-name: lumberjack
-
- [ I have no idea where the name came from... --r$ ]
-
- Enclosed is a program which monitors logfiles. It will alert the user to
- changes in one of the monitored files when in icon form (described in the
- manual page). It has been compiled and tested on SunOS 3.4, but should
- work with more recent versions of SunOS as well.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before the "#! /bin/sh" line,
- # then unpack it by saving it in a file and typing "sh file."
- # Contents : Makefile ljack.c ljack.l new1.icon new2.icon none.icon
- if `test ! -s Makefile`
- then
- echo "x - Makefile"
- cat > Makefile << '@\Rogue\Monster\'
- LIBS=-lsuntool -lsunwindow -lpixrect
- CFLAGS=-pipe
-
- ljack: ljack.c new1.icon new2.icon none.icon
- $(CC) $(CFLAGS) -o $@ ljack.c $(LIBS)
-
- install: ljack
- install -s -c ljack /usr/local
-
- clean:
- rm ljack
- @\Rogue\Monster\
- else
- echo "shar: Will not over write Makefile"
- fi
- if `test ! -s ljack.c`
- then
- echo "x - ljack.c"
- cat > ljack.c << '@\Rogue\Monster\'
- #include <stdio.h>
- #include <values.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <sys/time.h>
- #include <suntool/sunview.h>
- #include <suntool/frame.h>
- #include <suntool/textsw.h>
- #include <sunwindow/notify.h>
-
- /*
- * SunView size definitions. I shouldn't have to define these, but
- * there is no way to query SunView for them.
- */
- #define LMARGIN 5 /* left frame margin */
- #define RMARGIN 5 /* right frame margin */
- #define BMARGIN 5 /* bottom frame margin */
- #define SMARGIN 5 /* subwindow spacing */
-
- Frame frame;
- int files, updating = 0;
- Textsw text[16]; /* text subwindows */
- Menu menu[16]; /* menus for each subwindow */
- char *file[16]; /* filenames */
- off_t length[16]; /* file lengths */
- char alert[16]; /* flags: blink icon on update? */
-
- /*
- * Construct the icons.
- * None.icon is displayed when there are no new files; otherwise,
- * new1.icon and new2.icon are toggled once a second.
- */
- static short none_icon_i[] = {
- #include "none.icon"
- };
- mpr_static(none_icon_p, 64, 64, 1, none_icon_i);
-
- static short new1_icon_i[] = {
- #include "new1.icon"
- };
- mpr_static(new1_icon_p, 64, 64, 1, new1_icon_i);
-
- static short new2_icon_i[] = {
- #include "new2.icon"
- };
- mpr_static(new2_icon_p, 64, 64, 1, new2_icon_i);
-
- Icon ikes[3];
- int inum = 1;
- int newstuff;
-
- main(argc, argv)
- char **argv;
- {
- ikes[0] = icon_create(ICON_IMAGE, &none_icon_p, 0);
- ikes[1] = icon_create(ICON_IMAGE, &new1_icon_p, 0);
- ikes[2] = icon_create(ICON_IMAGE, &new2_icon_p, 0);
-
- frame = window_create(NULL, FRAME,
- FRAME_LABEL, "LUMBERJACK 1.0 by Steven Grimm (koreth@ssyx.ucsc.edu)",
- FRAME_ARGC_PTR_ARGV, &argc, argv,
- FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
- FRAME_ICON, ikes[0],
- WIN_ERROR_MSG, "Couldn't open window",
- 0);
-
- parse_args(argc, argv);
- create_subwindows();
- set_window_sizes();
- load_files();
-
- newstuff = 0;
- window_set(frame, FRAME_ICON, ikes[0], 0);
-
- set_notifier();
-
- window_main_loop(frame);
- }
-
- /*
- * Create all the necessary subwindows.
- */
- create_subwindows()
- {
- int i, domenu();
-
- for (i=0; i<files; i++)
- {
- menu[i] = menu_create(MENU_TITLE_ITEM, file[i],
- MENU_ACTION_ITEM, "Close", domenu,
- 0);
- text[i] = window_create(frame, TEXTSW,
- WIN_ERROR_MSG, "Couldn't create subwindow",
- WIN_IGNORE_PICK_EVENT, WIN_RESIZE,
- TEXTSW_DISABLE_CD, TRUE,
- TEXTSW_DISABLE_LOAD, TRUE,
- TEXTSW_INSERT_MAKES_VISIBLE, TEXTSW_ALWAYS,
- TEXTSW_IGNORE_LIMIT, TEXTSW_INFINITY,
- TEXTSW_MENU, menu[i],
- 0);
- }
- }
-
- /*
- * Set all the window sizes. This gets called whenever the base
- * frame gets resized, and once at initialization.
- *
- * For now, all the subwindows are assumed to be of equal size.
- */
- set_window_sizes()
- {
- int i, fr_height, fr_width, ts_height, ts_width;
-
- fr_height = (int)window_get(frame, WIN_HEIGHT) -
- (int)window_get(frame, WIN_TOP_MARGIN);
- fr_width = (int)window_get(frame, WIN_WIDTH) -
- LMARGIN - RMARGIN;
- ts_height = fr_height/files - SMARGIN;
- ts_width = fr_width;
-
- for (i=0; i<files; i++)
- {
- window_set(text[i],
- WIN_HEIGHT, ts_height,
- WIN_WIDTH, ts_width,
- 0);
- if (i)
- window_set(text[i], WIN_BELOW, text[i-1], 0);
- }
- }
-
- /*
- * Parse command line arguments.
- * For now, this is just a list of filenames.
- */
- parse_args(c, v)
- char **v;
- {
- int i, nflag = 0;
-
- files = 0;
- for (i=1; i<c; i++)
- {
- if (! strcmp(v[i], "-n"))
- nflag = 1;
- else if (access(v[i], R_OK) == 0)
- {
- file[files] = v[i];
- length[files] = MAXINT;
- alert[files] = !nflag;
- nflag = 0;
- if (++files == 16)
- break;
- }
- else
- perror(v[i]);
- }
- if (! files)
- exit(1);
- }
-
- /*
- * Load all the files into their windows, and place the cursors at the
- * infinity position. This gets called once every second.
- */
- load_files()
- {
- int i;
- struct stat st;
-
- for (i=0; i<files; i++)
- {
- if (stat(file[i], &st) < 0 || access(file[i], R_OK))
- {
- kill_file(i);
- continue;
- }
- if (st.st_size == length[i])
- continue;
- if (st.st_size < length[i]) /* file has gotten smaller */
- window_set(text[i], TEXTSW_FILE, file[i], 0);
- else if (st.st_size > length[i])
- {
- char *buf;
- int fd, bsiz;
-
- buf = (char *)malloc(bsiz = (st.st_size - length[i]));
- fd = open(file[i], O_RDONLY);
- if (fd < 0)
- {
- filerror:
- free(buf);
- kill_file(i);
- }
- if (lseek(fd, length[i], L_SET) < 0)
- goto filerror;
- if (read(fd, buf, bsiz) < 0)
- goto filerror;
-
- window_set(text[i],
- TEXTSW_INSERTION_POINT, TEXTSW_INFINITY,
- 0);
- textsw_insert(text[i], buf, bsiz);
- textsw_possibly_normalize(text[i], (Textsw_index)length[i]);
- free(buf);
- }
- length[i] = st.st_size;
- if (alert[i])
- newstuff++;
- }
- if (newstuff)
- if ((int)window_get(frame, FRAME_CLOSED))
- {
- inum ^= 3;
- window_set(frame, FRAME_ICON, ikes[inum], 0);
- }
- else
- {
- newstuff = 0;
- window_set(frame, FRAME_ICON, ikes[0], 0);
- }
- }
-
- /*
- * Handle events.
- */
- Notify_value
- event(window, event, arg, type)
- Window window;
- Event *event;
- Notify_arg arg;
- Notify_event_type type;
- {
- Notify_value value;
-
- value = notify_next_event_func(window, event, arg, type);
- if (event_id(event) == WIN_RESIZE)
- set_window_sizes();
- return(value);
- }
-
- /*
- * Handle a menu selection.
- */
- domenu(m, mi)
- Menu m;
- Menu_item mi;
- {
- int win;
-
- for (win = 0; win < files; win++)
- if (menu[win] == m)
- break;
- if (win == files)
- return;
- if ((int)menu_get(m, MENU_SELECTED) == 2)
- kill_file(win);
- }
-
- /*
- * Kill a file, either because we got an error reading it or because
- * the user said so.
- */
- kill_file(num)
- int num;
- {
- int i;
-
- menu_destroy(menu[num]);
- window_destroy(text[num]);
- if (num != files-1)
- {
- for (i = num+1; i < files; i++)
- {
- menu[i-1] = menu[i];
- text[i-1] = text[i];
- file[i-1] = file[i];
- length[i-1] = length[i];
- alert[i-1] = alert[i];
- }
- }
- if (num == 0)
- window_set(text[0], WIN_Y, 0, 0);
- if (--files == 0)
- exit(0);
- set_window_sizes();
- }
-
- /*
- * Set up a timer. It checks all the files once a second.
- * Also, tell the notifier what to do about resizes and so forth.
- */
- set_notifier()
- {
- static struct itimerval timer; /* this is our handle */
-
- bzero(&timer, sizeof(timer));
- timer.it_interval.tv_sec = 1;
- timer.it_value.tv_sec = 1;
- notify_set_itimer_func(&timer, load_files, ITIMER_REAL, &timer, NULL);
- notify_interpose_event_func(frame, event, NOTIFY_SAFE);
- }
- @\Rogue\Monster\
- else
- echo "shar: Will not over write ljack.c"
- fi
- if `test ! -s ljack.l`
- then
- echo "x - ljack.l"
- cat > ljack.l << '@\Rogue\Monster\'
- .TH LJACK LOCAL "2 September 1988"
- .SH NAME
- ljack \- monitor system logs
- .SH SYNOPSIS
- .B ljack
- [ -n ] file1 [[ -n ] file2 ... ]
- .SH DESCRIPTION
- .I Ljack
- (short for "lumberjack") runs under the SunView windowing environment. It
- monitors one or more logfiles, optionally alerting the user when an update
- takes place. The
- .BR file s
- specified on the command line should be readable by the user; if a file is
- not readable, no subwindow will be created for it.
- .PP
- .IR Ljack 's
- display is organized into a number of equal-sized subwindows, one for each
- .B file.
- The subwindows are standard text-editing windows (see
- .IR textedit (1))
- that can be scrolled and searched as usual. New information is added to the
- appropriate subwindow as it appears in a
- .B file,
- and the display scrolls to show the new data if necessary.
- .PP
- If
- .I ljack
- is in icon form when a
- .B file
- is updated, an animated axe chops at the log in the icon to inform the user
- that something new has arrived. The axe disappears when the icon is opened
- and closed again.
- .PP
- Up to sixteen
- .BR file s
- can be viewed; in some versions of SunOS (3.x and lower) there are not enough
- file descriptors to view more than six files.
- .SH OPTION
- .IP \fB\-n\fR
- If a
- .B file
- is preceded by a \-n argument, the axe will not appear when the
- .B file
- is updated.
- .SH AUTHOR
- Steven Grimm, koreth@ssyx.ucsc.edu
- .SH "SEE ALSO"
- textedit(1), suntools(1)
- @\Rogue\Monster\
- else
- echo "shar: Will not over write ljack.l"
- fi
- if `test ! -s new1.icon`
- then
- echo "x - new1.icon"
- cat > new1.icon << '@\Rogue\Monster\'
- /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
- */
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x01FF,0x0000,0x0000,0x0000,0x060F,0xFC00,0x0000,0x0000,
- 0x09F3,0xFFF8,0x0000,0x0000,0x1209,0xFFFF,0xE000,0x0000,
- 0x24E4,0xF7FF,0xFFC0,0x0000,0x2B1A,0xFFFF,0xFFF8,0x0000,
- 0x5209,0x7FF7,0xFFFC,0x0000,0x5445,0x77FF,0xFFBE,0x0000,
- 0x54A5,0x7FFF,0xFFFE,0x0000,0x5445,0x7FFF,0xFBFE,0x0000,
- 0x5209,0x7FFF,0xDFFE,0x0000,0x2B1A,0xFDFB,0x9FFE,0x0000,
- 0x24E4,0xFFFF,0x1EFC,0x0000,0x1209,0xFFFE,0x1FF8,0x0000,
- 0x09F3,0xBFBC,0x0FF0,0x0000,0x060F,0xFFF8,0x0C00,0x0000,
- 0x01FF,0xE010,0x0400,0x0000,0x0000,0x001E,0x0300,0x0000,
- 0x0000,0x0001,0xC180,0x0000,0x0000,0x0000,0xB0C0,0x0000,
- 0x0000,0x0000,0x98C0,0x0000,0x0000,0x0001,0x1D00,0x0000,
- 0x0000,0x0002,0x2600,0x0000,0x0000,0x0004,0x2000,0x0000,
- 0x0000,0x0004,0x4000,0x0000,0x0000,0x0008,0x8000,0x0000,
- 0x0000,0x0011,0x0000,0x0000,0x0000,0x0021,0x0000,0x0000,
- 0x0000,0x0022,0x0000,0x0000,0x0000,0x0044,0x0000,0x0000,
- 0x0000,0x0088,0x0000,0x0000,0x0000,0x0090,0x0000,0x0000,
- 0x0000,0x0110,0x0000,0x0000,0x0000,0x0220,0x0000,0x0000,
- 0x0000,0x0440,0x0000,0x0000,0x0000,0x0480,0x0000,0x0000,
- 0x0000,0x0880,0x0000,0x0000,0x0000,0x1100,0x0000,0x0000,
- 0x0000,0x2200,0x0000,0x0000,0x0000,0x2400,0x0000,0x0000,
- 0x0000,0x4400,0x0000,0x0000,0x0000,0x2800,0x0000,0x0000,
- 0x0000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x1000,0x0400,0x0040,0x0040,0x1049,0xA70C,0x5003,0x0E48,
- 0x1049,0x5492,0x68C0,0x9050,0x1049,0x549C,0x4043,0x9060,
- 0x1059,0x5490,0x4044,0x9050,0x1E29,0x570E,0x4042,0x8E48,
- 0x0000,0x0000,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000
- @\Rogue\Monster\
- else
- echo "shar: Will not over write new1.icon"
- fi
- if `test ! -s new2.icon`
- then
- echo "x - new2.icon"
- cat > new2.icon << '@\Rogue\Monster\'
- /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
- */
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x01FF,0x0000,0x0000,0x0000,0x060F,0xFC00,0x0000,0x0000,
- 0x09F3,0xFFF8,0x0000,0x0000,0x1209,0xFFFF,0xE000,0x0000,
- 0x24E4,0xF7FF,0xFFC0,0x0000,0x2B1A,0xFFFF,0xFFF8,0x0000,
- 0x5209,0x7FF7,0xFFFC,0x0000,0x5445,0x77FF,0xFFBE,0x0000,
- 0x54A5,0x7FFF,0xFFFE,0x0000,0x5445,0x7FFF,0xFBFE,0x0000,
- 0x5209,0x7FFF,0xFFFE,0x0000,0x2B1A,0xFDFB,0xFFFE,0x0000,
- 0x24E4,0xFFFF,0xFEFC,0x0000,0x1209,0xFFFF,0xFFF8,0x0000,
- 0x09F3,0xBFBF,0xFFF0,0x0000,0x060F,0xFFFF,0x0000,0x0000,
- 0x01FF,0xE000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0000,
- 0x0000,0x0000,0x00C8,0x0000,0x0000,0x0000,0x0310,0x0000,
- 0x0000,0x0000,0x0C10,0x0000,0x0000,0x0000,0x3010,0x0000,
- 0x0000,0x0000,0x3810,0x0000,0x0000,0x0000,0x0610,0x0000,
- 0x0000,0x0000,0x0118,0x0000,0x0000,0x0000,0x0108,0x0000,
- 0x0000,0x0000,0x0684,0x0000,0x0000,0x0000,0x0884,0x0000,
- 0x0000,0x0000,0x3066,0x0000,0x0000,0x0000,0x4198,0x0000,
- 0x0000,0x0001,0x8210,0x0000,0x0000,0x0002,0x0C00,0x0000,
- 0x0000,0x000C,0x3000,0x0000,0x0000,0x0010,0x4000,0x0000,
- 0x0000,0x0061,0x8000,0x0000,0x0000,0x0082,0x0000,0x0000,
- 0x0000,0x030C,0x0000,0x0000,0x0000,0x0410,0x0000,0x0000,
- 0x0000,0x1860,0x0000,0x0000,0x0000,0x2180,0x0000,0x0000,
- 0x0000,0x2200,0x0000,0x0000,0x0000,0x1C00,0x0000,0x0000,
- 0x0000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x1000,0x0400,0x0040,0x0040,0x1049,0xA70C,0x5003,0x0E48,
- 0x1049,0x5492,0x68C0,0x9050,0x1049,0x549C,0x4043,0x9060,
- 0x1059,0x5490,0x4044,0x9050,0x1E29,0x570E,0x4042,0x8E48,
- 0x0000,0x0000,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000
- @\Rogue\Monster\
- else
- echo "shar: Will not over write new2.icon"
- fi
- if `test ! -s none.icon`
- then
- echo "x - none.icon"
- cat > none.icon << '@\Rogue\Monster\'
- /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
- */
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x01FF,0x0000,0x0000,0x0000,0x060F,0xFC00,0x0000,0x0000,
- 0x09F3,0xFFF8,0x0000,0x0000,0x1209,0xFFFF,0xE000,0x0000,
- 0x24E4,0xF7FF,0xFFC0,0x0000,0x2B1A,0xFFFF,0xFFF8,0x0000,
- 0x5209,0x7FF7,0xFFFC,0x0000,0x5445,0x77FF,0xFFBE,0x0000,
- 0x54A5,0x7FFF,0xFFFE,0x0000,0x5445,0x7FFF,0xFBFE,0x0000,
- 0x5209,0x7FFF,0xFFFE,0x0000,0x2B1A,0xFDFB,0xFFFE,0x0000,
- 0x24E4,0xFFFF,0xFEFC,0x0000,0x1209,0xFFFF,0xFFF8,0x0000,
- 0x09F3,0xBFBF,0xFFF0,0x0000,0x060F,0xFFFF,0x0000,0x0000,
- 0x01FF,0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x1000,0x0400,0x0040,0x0040,0x1049,0xA70C,0x5003,0x0E48,
- 0x1049,0x5492,0x68C0,0x9050,0x1049,0x549C,0x4043,0x9060,
- 0x1059,0x5490,0x4044,0x9050,0x1E29,0x570E,0x4042,0x8E48,
- 0x0000,0x0000,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000
- @\Rogue\Monster\
- else
- echo "shar: Will not over write none.icon"
- fi
- # to concatenate archives, remove anything after this line
- exit 0
-
-